﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using GMusicBox.Core;
using GMusicBox.Core.Setting;
using System.Net;

namespace GMusicBox
{
    public partial class frmMain : Form
    {
        #region 构造函数 & 初始化函数
        #region 构造函数
        public frmMain()
        {
            InitializeComponent();

            be = new BassEngine(this.Handle);
            be.PlayStateChanged += new EventHandler(be_PlayStateChanged);
            be.Tick += new EventHandler(be_Tick);

            mder.Connected += new EventHandler(mder_Connected);

            playing[0] = -1; playing[1] = -1; playing[2] = -1;

            Initialize();
        }
        #endregion
        #region 初始化函数
        private void Initialize()
        {
            InitializeMiniMode();
            InitializeFromThreads();
            InitializeSongList();
            InitializeProfile();
            InitializeUI();
        }

        private void InitializeCharts()
        {
            try
            {
                songs[1] = new List<MusicList>();
                string[] charts = Program.Charts;
                for (int i = 0; i < charts.Length; i++)
                {
                    MusicList ml = new MusicList(charts[i], "");
                    ml.GetChartData();
                    songs[1].Add(ml);

                    ListViewItem lvi = new ListViewItem(ml.Name);
                    lvi.Tag = new int[] { 1, i };
                    lvwCharts.Items.Add(lvi);
                }
            }
            catch { }
        }

        private void InitializeFromThreads()
        {
            initChart = new Thread(new ThreadStart(InitializeCharts));
            initChart.SetApartmentState(ApartmentState.STA);
            initChart.Start();

            initTopic = new Thread(new ThreadStart(InitializeTopiclistings));
            initTopic.SetApartmentState(ApartmentState.STA);
            initTopic.Start();
        }

        private void InitializeFX()
        {
            feq = new frmEQ(be);
            feq.FormClosing += new FormClosingEventHandler(feq_FormClosing);

            string[] dsp = FXSetting.EnabledDsp;
            for (int i = 0; i < dsp.Length; i++)
                be.AddDSP(dsp[i]);
        }

        public void InitializeHotkeys()
        {
            if (hotkey != null) hotkey.UnregisterHotkeys();
            hotkey = new HotKey(this.Handle);

            string[] hks = StandardSetting.HotKeys.Split('|');
            for (int i = 0; i < hks.Length; i++)
            {
                if (StandardSetting.HotKey)
                {
                    string[] hk = hks[i].Split(',');
                    HotKey.KeyFlags kf = new HotKey.KeyFlags();
                    if (Convert.ToBoolean(hk[0])) kf |= HotKey.KeyFlags.MOD_CONTROL;
                    if (Convert.ToBoolean(hk[1])) kf |= HotKey.KeyFlags.MOD_SHIFT;
                    if (Convert.ToBoolean(hk[2])) kf |= HotKey.KeyFlags.MOD_ALT;
                    hotkeys[i] = hotkey.RegisterHotkey((Keys)int.Parse(hk[3]), kf);
                }
                else hotkeys[i] = -1;
            }

            if (StandardSetting.MultimediaKeyboard)
            {
                hotkeys[7] = hotkey.RegisterHotkey(Keys.MediaPlayPause, HotKey.KeyFlags.MOD_NONE);
                hotkeys[8] = hotkey.RegisterHotkey(Keys.MediaPreviousTrack, HotKey.KeyFlags.MOD_NONE);
                hotkeys[9] = hotkey.RegisterHotkey(Keys.MediaNextTrack, HotKey.KeyFlags.MOD_NONE);
            }
            else
            {
                hotkeys[7] = -1;
                hotkeys[8] = -1;
                hotkeys[9] = -1;
            }

            hotkey.OnHotKey += new HotKey.HotkeyEventHandler(hotkey_OnHotKey);
        }

        private void InitializeMiniMode()
        {
            fm = new frmMini(this);
            fm.btnPrevious.Click += new EventHandler(btnPrevious_Click);
            fm.btnPlayPause.Click += new EventHandler(btnPlayPause_Click);
            fm.btnNext.Click += new EventHandler(btnNext_Click);
            fm.btnDesktopLyric.Click += new EventHandler(mnuShowOrHideDesktopLyric_Click);
            fm.btnMute.Click += new EventHandler(btnMute_Click);
            fm.FormClosing += new FormClosingEventHandler(fm_FormClosing);
        }

        private void InitializeProfile()
        {
            lyricShow1.UpdateSkin();

            tVolume.Value = MainSetting.Volume;
            fm.tVolume.Value = MainSetting.Volume;
            be.Mute = MainSetting.Mute;
            loopMode = MainSetting.LoopMode;

            bool ad = StandardSetting.ShowAd; 
            if (ad) webBrowser1.Navigate("http://pagead2.googlesyndication.com/pagead/ads?client=ca-pub-1045560459139079&output=html&h=90&slotname=4784027349&w=728&ea=0&flash=10.1.82&hints=%E6%B3%A8%E5%86%8C%20%E4%B8%AD%E6%96%87%20%E8%A7%86%E9%A2%91%20%E6%8A%80%E6%9C%AF%20%E5%A4%A7%E5%AD%A6%20%E8%AE%BA%E5%9D%9B%20%E6%97%85%E6%B8%B8%20%E8%82%A1%E7%A5%A8%20%E7%95%99%E5%AD%A6%20%E5%87%BA%E5%9B%BD%20%E7%A7%BB%E6%B0%91%20nba%20bt%20cctv%203g%20mac%20ie%20windows%20microsoft%20download&url=top100.cn&dt=1282102196127&shv=r20100804&correlator=1282102196132&dblk=1&frm=1&adk=342823052&ga_vid=1441465170.1282102196&ga_sid=1282102196&ga_hid=1240411935&ga_fc=0&u_tz=480&u_his=2&u_java=1&u_h=800&u_w=1280&u_ah=760&u_aw=1280&u_cd=32&u_nplug=19&u_nmime=70&biw=-12245933&bih=-12245933&ifk=1151587861&loc=http://www.google.cn/music/top100/player_page&fu=0&ifi=1&dtd=35");
            this.ClientSize = new System.Drawing.Size(740, (ad ? 570 : 468));
        }

        private void InitializeSongList()
        {
            songs[0] = new List<MusicList>();
            DirectoryInfo di = new DirectoryInfo(Settings.SettingSavePath + "\\Config\\PlayLists");
            if (di.Exists)
            {
                FileInfo[] fi = di.GetFiles("list*.xml");
                if (fi.Length != 0)
                {
                    for (int i = 0; i < fi.Length; i++)
                    {
                        MusicList ml = new MusicList();
                        ml.Load(fi[i].FullName);
                        songs[0].Add(ml);
                    }
                }
                else songs[0].Add(new MusicList("", "默认列表"));
            }
            else songs[0].Add(new MusicList("", "默认列表"));

            for (int i = 0; i < songs[0].Count; i++)
            {
                ListViewItem lvi = new ListViewItem(songs[0][i].Name);
                lvi.Tag = new int[] { 0, i };
                lvwLists.Items.Add(lvi);
            }

            if (MainSetting.LastSelected[0] == 0 && lvwLists.Items.Count < MainSetting.LastSelected[1]) lvwLists.Items[MainSetting.LastSelected[1]].Selected = true;
            else lvwLists.Items[0].Selected = true;
        }

        private void InitializeTopiclistings()
        {
            try
            {
                songs[2] = new List<MusicList>();
                MusicList[] t = MusicList.GetTopiclistings();
                if (t == null)
                {
                    ShowMsg("专题列表加载失败");
                    return;
                }

                songs[2].AddRange(t);

                for (int i = 0; i < songs[2].Count; i++)
                {
                    ListViewItem lvi = new ListViewItem(songs[2][i].Name);
                    lvi.Tag = new int[] { 2, i };
                    lvwTopiclistings.Items.Add(lvi);
                }
            }
            catch { }
        }

        private void InitializeUI()
        {
            if (loopMode == 0) btnRandom.NormalImage = res.random_checked;
            else if (loopMode == 1) btnforAll.NormalImage = res.forall_checked;
            else btnaFor.NormalImage = res.afor_checked;

            btnAddTo.Text = "添加到";
            btnDelete.Text = "删除";
            btnConfig.Text = "选项";
            btnDownloads.Text = "下载管理器";

            RefreshMuteState();
            lvwMusics.ContextMenu = mnuMusic;
            lvwLists.ContextMenu = mnuList;

            mder.DownloadCompleted += new EventHandler(mder_DownloadComplete);
            txtSearch.GotFocus += new EventHandler(txtSearch_GotFocus);
            txtSearch.LostFocus += new EventHandler(txtSearch_LostFocus);
            lyricShow1.DContextMenu = mnuNotify;

            this.Location = new Point(Screen.PrimaryScreen.Bounds.Width / 2 - this.Width / 2, Screen.PrimaryScreen.Bounds.Height / 2 - this.Height / 2);
            this.TopMost = Core.Setting.StandardSetting.TopMost;

            if (Environment.OSVersion.Version.Major < 6)
            {
                lvwMusics.SmallImageList = imageList2;
                lvwCharts.SmallImageList = imageList2;
                lvwLists.SmallImageList = imageList2;
                lvwTopiclistings.SmallImageList = imageList2;
            }
        }
        #endregion
        #endregion
        #region 变量
        public frmDownloader     fder = null;
        public BassEngine        be;
        public bool              mhid = true,
                                 mshw = false,
                                 closed = false,
                                 eqshw = false;

        public List<MusicList>[] songs = new List<MusicList>[3];
        public int[]             selected = new int[2];
        public int[]             playing = new int[3];
        bool                     showedtip = false,
                                 hid = false,
                                 closefmenu = false;
        double                   lastplay = 0;
        int                      lastDownload = 0;
        int                      loopMode = 1;
        int                      lvwMusicClick = 0;
        string                   msg = "";
        frmPlayTip               fpt = null;
        Downloader               mder = new Downloader();
        HotKey                   hotkey;
        int[]                    hotkeys = new int[10];
        Thread                   initChart, initTopic;
        public frmMini           fm;
        public frmEQ             feq;

        delegate void Action();
        delegate void LoadPictureCallBack(Song song, SongStreaming ss);
        delegate void ShowMsgCallBack(string s);

        private Song PlayingSong
        {
            get
            {
                if (playing[0] == -1 || playing[1] == -1 || playing[2] == -1) return null;
                return songs[playing[0]][playing[1]][playing[2]];
            }
        }
        #endregion
        #region 自定义函数
        public void AddItemToMusic(Song item)
        {
            string[] ss = new string[] { item.Name, item.Artist.ToString(), item.Album.Name, double2Time(item.Duration) };
            lvwMusics.Items.Add(new ListViewItem(ss));
        }

        public void AddTask(Song[] tasks)
        {
            bool same = false;
            bool lrc = MainSetting.LastDownloadLyric;
            string ns = MainSetting.LastDownloadNameRules;
            string dp = MainSetting.LastDownloadSavePath;
            bool added = false;

            for (int i = 0; i < tasks.Length; i++)
            {
                if (same)
                {
                    DownloadTask dt = new DownloadTask(tasks[i]);
                    dt.FileName = dp + Helper.ReplaceDownloadStrings(ns, tasks[i]);
                    fder.dt.Add(dt);

                    if (lrc)
                    {
                        DownloadTask ldt = new DownloadTask(tasks[i]);
                        ldt.FileName = Path.GetDirectoryName(dt.FileName) + "\\" + Path.GetFileNameWithoutExtension(dt.FileName) + ".lrc";
                        ldt.IsLyrics = true;
                        fder.dt.Add(ldt);
                    }
                    added = true;
                }
                else
                {
                    frmHowToDownload f = new frmHowToDownload(tasks[i].Id, dp == "" ? Settings.SettingSavePath + "\\Downloads\\" : dp, Helper.ReplaceDownloadStrings(ns, tasks[i]));
                    f.checkBox1.Checked = lrc;
                    if (f.ShowDialog() == DialogResult.OK)
                    {
                        if (!f.textBox2.Text.EndsWith("\\")) f.textBox2.Text += "\\";
                        lrc = f.checkBox1.Checked;
                        same = f.checkBox2.Checked;
                        dp = f.textBox2.Text;
                        ns = f.textBox3.Text.Replace(tasks[i].Name, "${name}").Replace(tasks[i].Artist.ToString(), "${artist}").Replace(tasks[i].Album.Name, "${album}").Replace(".mp3", "");

                        DownloadTask dt = new DownloadTask(tasks[i]);
                        dt.FileName = f.textBox2.Text + f.textBox3.Text;
                        fder.dt.Add(dt);

                        if (lrc)
                        {
                            DownloadTask ldt = new DownloadTask(tasks[i]);
                            ldt.FileName = f.textBox2.Text + Path.GetFileNameWithoutExtension(f.textBox3.Text) + ".lrc";
                            ldt.IsLyrics = true;
                            fder.dt.Add(ldt);
                        }

                        MainSetting.LastDownloadLyric = lrc;
                        MainSetting.LastDownloadNameRules = ns;
                        MainSetting.LastDownloadSavePath = dp;
                        MainSetting.Save();
                        added = true;
                    }
                }
            }
            fder.AddRow();
            fder.RefreshTask();

            if (added)
            {
                fder.Show();
                fder.WindowState = FormWindowState.Normal;
            }
        }

        private string double2Time(double d)
        {
            if (d < 0) return "00:00";
            TimeSpan ts = TimeSpan.FromSeconds(d);
            return new DateTime(ts.Ticks).ToString("mm:ss");
        }

        private void EraserInfos()
        {
            //清除播放信息
            lblMusicName.Text = "欢迎使用谷歌音乐盒！";
            lnkMusicArtist.Text = "";
            label2.Text = "/ 00:00";
            label1.Text = "00:00";
            this.Text = "谷歌音乐盒";
            nfyMain.Text = "谷歌音乐盒";
            lyricShow1.CurrentProgress = 0;
            lyricShow1.SetLyric(null);
            ShowTextOnLyricShow("欢迎使用谷歌音乐盒");
            pictureBox4.Image = null;
            playing[0] = -1; playing[1] = -1; playing[2] = -1;
        }
        
        private string GetCachePath(Song song)
        {
            //获取某一首歌的缓存地址
            return Helper.GetCachePath(Helper.CacheType.Music, song.Id + ".mp3");
        }

        private void LoadPicture(Song song, SongStreaming ss)
        {
            //加载专辑封面
            if (this.InvokeRequired)
            {
                try
                {
                    LoadPictureCallBack lp = new LoadPictureCallBack(LoadPicture);
                    this.Invoke(lp, song, ss);
                }
                catch { }
            }
            else
            {
                string path = Helper.GetCachePath(Helper.CacheType.Thumbnail, song.Album.Id + ".jpg");
                if (File.Exists(path))
                {
                    pictureBox4.Image = new Bitmap(path);
                    fpt.ImageOK();
                }
                else if (ss != null && ss.AlbumThumbnailLink == null)
                    pictureBox4.Image = new Bitmap(1, 1);
                else if (ss.AlbumThumbnailLink != "")
                {
                    pictureBox4.Tag = path;
                    pictureBox4.LoadAsync(ss.AlbumThumbnailLink);
                }
            }
        }

        private void RefreshInfos()
        {
            //更新正在播放信息
            string nmt = PlayingSong.Name + " - 谷歌音乐盒";
            if (nmt.Length > 60) nmt = PlayingSong.Name.Substring(0, 47) + "... - 谷歌音乐盒";
            nfyMain.Text = nmt;

            lblMusicName.Text = nmt.Replace("谷歌音乐盒", "");
            this.Text = PlayingSong.Name + " - 谷歌音乐盒 ";
            lnkMusicArtist.Text = PlayingSong.Artist.ToString();
            if (be.Handle != 0)
            {
                DateTime d = new DateTime();
                d = d.AddSeconds(PlayingSong.Duration);
                label2.Text = "/ " + d.ToString("mm:ss");
            }
            else label2.Text = "/ 00:00";
            lnkMusicArtist.Left = lblMusicName.Left + lblMusicName.Width - 6;

            if (lnkMusicArtist.Text.Trim() == "") lblMusicName.Text += "未知作曲者";
        }

        public void RefreshMuteState()
        {
            if (be.Mute)
            {
                btnMute.NormalImage = res.muted;
                btnMute.EnterImage = res.muted_enter;
                btnMute.DowningImage = res.muted_down;
                fm.btnMute.NormalImage = res.muted;
                fm.btnMute.EnterImage = res.muted_enter;
                fm.btnMute.DowningImage = res.muted_down;
            }
            else
            {
                btnMute.NormalImage = res.mute;
                btnMute.EnterImage = res.mute_enter;
                btnMute.DowningImage = res.mute_down;
                fm.btnMute.NormalImage = res.mute;
                fm.btnMute.EnterImage = res.mute_enter;
                fm.btnMute.DowningImage = res.mute_down;
            }
        }

        private void SaveAllLists()
        {
            //保存全部列表
            DirectoryInfo di = new DirectoryInfo(Settings.SettingSavePath + "\\Config\\PlayLists");
            FileInfo[] fi = di.GetFiles("list*.xml");
            foreach (FileInfo item in fi)
                item.Delete();
            for (int i = 0; i < songs[0].Count; i++)
                SaveList(i);
        }

        private void SaveList()
        {
            //保存当前列表
            SaveList(selected[1]);
        }

        public void SaveList(int index)
        {
            //保存指定的列表
            Helper.CreateDirectory(Settings.SettingSavePath + "\\Config\\PlayLists\\list");
            songs[0][index].Save(Settings.SettingSavePath + "\\Config\\PlayLists\\list" + index.ToString() + ".xml");
        }

        private void SetPlaying(int index)
        {
            //播放一首歌
            SetPlaying(playing[1], index);
        }

        private void SetPlaying(int list, int index)
        {
            //播放一首歌
            SetPlaying(playing[0], list, index);
        }

        public void SetPlaying(int type, int list, int index)
        {
            backgroundWorker2.CancelAsync();
            try { backgroundWorker2.RunWorkerAsync(); }
            catch { }
            if (playing[2] != -1 && songs[type][list][index].Id == PlayingSong.Id && File.Exists(GetCachePath(PlayingSong)))
            {
                be.Position = TimeSpan.FromSeconds(0);
                be.Load(GetCachePath(PlayingSong), PlayingSong.ToString());
                be.Play();
                return;
            }

            playing[0] = type;
            playing[2] = index;
            playing[1] = list;

            label1.Text = "00:00";
            be.Stop();
            be.Position = TimeSpan.FromSeconds(0);
            lyricShow1.CurrentProgress = 0;

            if (GetCachePath(PlayingSong) != mder.FileName) mder.Stop();
            ShowMsg("正在加载歌曲");
            RefreshInfos();
            ShowPlayingArrow(false);

            backgroundWorker1.CancelAsync();
            try { backgroundWorker1.RunWorkerAsync(); }
            catch
            {
                this.backgroundWorker1.Dispose();
                this.backgroundWorker1 = new BackgroundWorker();
                this.backgroundWorker1.WorkerSupportsCancellation = true;
                this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
                this.backgroundWorker1.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.backgroundWorker1_RunWorkerCompleted);
                this.backgroundWorker1.RunWorkerAsync();
            }

            ShowTextOnLyricShow(PlayingSong.ToString());
            lastplay = 0; lastDownload = 0;
            mder.DownloadedSize = 0; mder.FileLenght = 0;
            timer2.Enabled = true;
            be.IsTimerEnabled = true;
        }

        private void ShowPlaying()
        {
            //显示“正在播放”窗口
            if (StandardSetting.ShowNowPlaying)
            {
                if (showedtip) fpt.Close();
                showedtip = true;
                fpt = new frmPlayTip(PlayingSong);
                fpt.FormClosed += delegate(object sender, FormClosedEventArgs e) { showedtip = false; };
                fpt.ImageOK();
                fpt.Show();
            }
        }

        private void ShowPlayingArrow(bool onlyPlaying)
        {
            //刷新正在播放指示
            //onlyPlaying：仅在播放时显示，否则移除正在播放指示

            for (int i = 0; i < lvwMusics.Items.Count; i++)
            {
                lvwMusics.Items[i].ForeColor = Color.Black;
                lvwMusics.Items[i].ImageIndex = -1;
            } 
            
            for (int i = 0; i < lvwCharts.Items.Count; i++)
            {
                lvwCharts.Items[i].ForeColor = Color.Black;
                lvwCharts.Items[i].ImageIndex = -1;
            } 
            
            for (int i = 0; i < lvwLists.Items.Count; i++)
            {
                lvwLists.Items[i].ForeColor = Color.Black;
                lvwLists.Items[i].ImageIndex = -1;
            } 
            
            for (int i = 0; i < lvwTopiclistings.Items.Count; i++)
            {
                lvwTopiclistings.Items[i].ForeColor = Color.Black;
                lvwTopiclistings.Items[i].ImageIndex = -1;
            }

            if ((onlyPlaying && playing[2] != -1) || !onlyPlaying)
            {
                if (playing[0] == selected[0] && playing[1] == selected[1] && lvwMusics.Items.Count > playing[2])
                {
                    lvwMusics.Items[playing[2]].ForeColor = Color.Blue;
                    lvwMusics.Items[playing[2]].ImageIndex = 0;
                }
                if (playing[0] == 0)
                {
                    lvwLists.Items[playing[1]].ForeColor = Color.Blue;
                    lvwLists.Items[playing[1]].ImageIndex = 0;
                }
                else if (playing[0] == 1)
                {
                    lvwCharts.Items[playing[1]].ForeColor = Color.Blue;
                    lvwCharts.Items[playing[1]].ImageIndex = 0;
                }
                else if (playing[0] == 2)
                {
                    lvwTopiclistings.Items[playing[1]].ForeColor = Color.Blue;
                    lvwTopiclistings.Items[playing[1]].ImageIndex = 0;
                }
            }
        }

        public void ShowMsg(string s)
        {
            //显示消息
            if (this.InvokeRequired)
            {
                try
                {
                    ShowMsgCallBack sm = new ShowMsgCallBack(ShowMsg);
                    this.Invoke(sm, s);
                }
                catch { }
            }
            else
            {
                if (s == "") timer5_Tick(timer5, null);
                else
                {
                    panel3.Visible = true;
                    panel3.Width = TextRenderer.MeasureText(s, label4.Font).Width + 8;
                    panel3.Left = panel1.Width / 2 - panel3.Width / 2;
                    label4.Text = s;

                    msg = s;
                    if (msg == "正在加载歌曲") return;
                    timer5.Enabled = true;
                    timer5.Start();
                }
            }
        }

        private void ShowTextOnLyricShow(string text)
        {
            lyricShow1.ShowText(text);
        }

        private void ConnectionFailed()
        {
            timer1.Enabled = false;
            timer2.Enabled = false;
            timer3.Enabled = false;
            be.Pause();
            be.CloseFile();
            EraserInfos();
            ShowMsg("歌曲连接失败");
        }
        #endregion
        #region 窗体事件 & 播放状态更改时
        protected override void WndProc(ref Message m)
        {
            if (StandardSetting.MinimizeToTray && m.Msg == 274 && m.WParam.ToInt32() == 61472) //WM_SYSCOMMAND, SC_MINIMIZE
            {
                nfyMain_DoubleClick(null, null);
                return;
            }

            base.WndProc(ref m);
            if (hotkey != null) hotkey.PreFilterMessage(ref m);
        }

        private void fm_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                if (fm.Visible) return;
                this.Show();
                mhid = true;
                mshw = false;
            }
            catch { }
        }

        private void feq_FormClosing(object sender, FormClosingEventArgs e)
        {
            eqshw = false;
        }

        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            bool close = true;
            if (!closefmenu)
            {
                if (StandardSetting.CloseEvent == 0)
                {
                    frmCloseEvent f = new frmCloseEvent();
                    if (MainSetting.LastSelectedCloseEvent == 0) f.rdoClose.Checked = true;
                    else f.rdoNotify.Checked = true;

                    if (f.ShowDialog() == DialogResult.OK)
                    {
                        if (f.rdoNotify.Checked) close = false;
                        if (f.chkNotAgain.Checked) StandardSetting.CloseEvent = f.rdoNotify.Checked ? 1 : 2;
                        StandardSetting.Save();

                        MainSetting.LastSelectedCloseEvent = f.rdoNotify.Checked ? 1 : 0;
                    }
                    else
                    {
                        e.Cancel = true;
                        return;
                    }
                }
                else if (StandardSetting.CloseEvent == 1) close = false;
            }

            if (close)
            {
                closed = true;
                if (initChart != null && initChart.ThreadState != ThreadState.Stopped) initChart.Abort();
                if (initTopic != null && initTopic.ThreadState != ThreadState.Stopped) initTopic.Abort();
                hotkey.UnregisterHotkeys();
                fder.dwr.Stop();
                be.Stop();
                be.Free();

                MainSetting.Volume = be.Volume;
                MainSetting.Mute = be.Mute;
                MainSetting.LoopMode = loopMode;
                MainSetting.LastDesktopLyricVisible = (!lyricShow1.DVisible);
                MainSetting.LastDesktopLyricWidth = lyricShow1.fdl.Width;
                MainSetting.LastDesktopLyricLocation = lyricShow1.fdl.Location;
                MainSetting.LastDesktopLyricLock = lyricShow1.fdl.trans;
                MainSetting.LastPlay = playing;
                MainSetting.LastSelected = selected;
                MainSetting.Save();

                mder.Stop();
            }
            else
            {
                e.Cancel = true;
                nfyMain_DoubleClick(null, null);
            }
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            InitializeHotkeys();
            InitializeFX();

            if (StandardSetting.AutoStart)
            {
                int[] play = MainSetting.LastPlay;
                if (play[0] == -1 || play[1] == -1 || play[2] == -1 || play[0] != 0)
                { play[0] = 0; play[1] = 0; play[2] = 0; }

                if (songs[play[0]][play[1]].Songs.Count > play[2])
                    SetPlaying(play[0], play[1], play[2]);
            }

            lyricShow1.ShowDesktopLyric(!MainSetting.LastDesktopLyricVisible);
            lyricShow1.ShowText("欢迎使用谷歌音乐盒！");
            lyricShow1.EnabledShowText = false;
            if (MainSetting.LastDesktopLyricLock) lyricShow1.Penetrate();

            fder = new frmDownloader();

            try
            {
                if (File.Exists(Application.StartupPath + "\\updater.exe.tmp"))
                {
                    try
                    {
                        File.Move(Application.StartupPath + "\\updater.exe", Application.StartupPath + "\\updater.exe.bak");
                        File.Move(Application.StartupPath + "\\updater.exe.tmp", Application.StartupPath + "\\updater.exe");
                        File.Delete(Application.StartupPath + "\\updater.exe.bak");
                    }
                    catch { }
                }
                System.Diagnostics.Process.Start(Application.StartupPath + "\\updater.exe", "\"" + Application.ExecutablePath + "\" " + res.Version);
            }
            catch { }
        }

        private void frmMain_TextChanged(object sender, EventArgs e)
        {
            fm.Text = this.Text;
        }

        private void be_PlayStateChanged(object sender, EventArgs e)
        {
            try
            {
                if (be.Handle != 0)
                {
                    if (PlayingSong.Duration != 0)
                        lyricShow1.Duration = PlayingSong.Duration;

                    DateTime d = new DateTime();
                    d = d.AddSeconds(PlayingSong.Duration);
                    label2.Text = "/ " + d.ToString("mm:ss");
                }

                if (be.PlayState == BassPlayState.Playing)
                {
                    if (!timer1.Enabled)
                    {
                        timer1.Enabled = true;
                        timer2.Enabled = true;
                        if (StandardSetting.Subtitle) timer3.Enabled = true;
                    }
                }
                else
                {
                    try
                    {
                        if (be.PlayState == BassPlayState.MusicEnded && be.Duration.TotalSeconds < PlayingSong.Duration)
                        {
                            lastDownload = mder.DownloadedSize;
                            lastplay = be.Position.TotalSeconds;
                            be.IsTimerEnabled = true;
                            return;
                        }
                    }
                    catch { }

                    if (timer1.Enabled)
                    {
                        if (be.Handle == 0) return;
                        timer1.Enabled = false;
                        timer2.Enabled = false;
                        timer3.Enabled = false;
                        if (be.PlayState == BassPlayState.Stopped) this.Text = "谷歌音乐盒";
                        else this.Text = PlayingSong.Name + " - 谷歌音乐盒 ";
                        if (be.Handle != 0 && be.PlayState == BassPlayState.MusicEnded && (be.Position.TotalSeconds >= PlayingSong.Duration || be.Position.TotalSeconds == 0))
                        {
                            lyricShow1.EnabledShowText = false; lyricShow1.Invalidate();
                            label1.Text = "00:00";
                            if (loopMode != 2)
                            {
                                int needplay = (int)(Microsoft.VisualBasic.VBMath.Rnd() * songs[playing[0]][playing[1]].Songs.Count);

                                if (loopMode == 0)
                                    needplay = (int)(Microsoft.VisualBasic.VBMath.Rnd() * songs[playing[0]][playing[1]].Songs.Count);
                                else if (loopMode == 1)
                                {
                                    needplay = playing[2];
                                    if (playing[2] != songs[playing[0]][playing[1]].Songs.Count - 1) needplay++;
                                    else needplay = 0;
                                }
                                SetPlaying(playing[1], needplay);
                            }
                            else
                            {
                                be.Position = TimeSpan.FromSeconds(0);
                                be.Play();
                                ShowTextOnLyricShow(PlayingSong.ToString());
                            }
                        }
                        if (label1.Text == "") label1.Text = "00:00";
                    }
                }

                if (be.PlayState == BassPlayState.Playing)
                {
                    btnPlayPause.NormalImage = res.pause_normal;
                    btnPlayPause.EnterImage = res.pause_enter;
                    btnPlayPause.DowningImage = res.pause_normal;
                    fm.btnPlayPause.NormalImage = res.m_pause;
                    fm.btnPlayPause.EnterImage = res.m_pause_enter;
                    fm.btnPlayPause.DowningImage = res.m_pause_down;
                }
                else
                {
                    btnPlayPause.NormalImage = res.play_normal;
                    btnPlayPause.EnterImage = res.play_enter;
                    btnPlayPause.DowningImage = res.play_normal;
                    fm.btnPlayPause.NormalImage = res.m_play;
                    fm.btnPlayPause.EnterImage = res.m_play_enter;
                    fm.btnPlayPause.DowningImage = res.m_play_down;
                }
            }
            catch { }
        }
        #endregion
        #region 绘图事件 & 各种BackgroundWorker事件
        #region 绘图事件
        private void panel3_Paint(object sender, PaintEventArgs e)
        {
            GraphicsPath roundedRect = Helper.CreateRoundedRectangle(panel3.ClientRectangle, 5);
            SolidBrush sb = new SolidBrush(Color.FromArgb(255, 241, 167));

            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            e.Graphics.FillPath(sb, roundedRect);
            panel3.Region = new Region(roundedRect);

            roundedRect.Dispose();
            sb.Dispose();
        }

        private void panProgress_Paint(object sender, PaintEventArgs e)
        {
            try
            {
                if (hid) return;
                if (mder.IsDownloadCompleted)
                    e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(216, 216, 216)), new Rectangle(1, 1, panProgress.Width - 3, 3));
                else e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(216, 216, 216)), new Rectangle(1, 1, (int)((panProgress.Width - 3) / (double)mder.FileLenght * mder.DownloadedSize), 3));

                if (PlayingSong == null) return;
                if (be.PlayState != BassPlayState.Stopped)
                {
                    //if (be.PlayState == BassPlayState.Stopped || wmp.currentMedia == null)
                    //{
                    //    e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(180, 210, 241)), new Rectangle(1, 1, 0, 2));
                    //    e.Graphics.DrawLine(new Pen(Color.FromArgb(102, 148, 227)), new Point(1, 3), new Point(0, 3));
                    //}
                    if (be.PlayState == BassPlayState.Playing || be.PlayState == BassPlayState.Paused || (be.PlayState == BassPlayState.MusicEnded && be.Duration.TotalSeconds <= PlayingSong.Duration))
                    {
                        try
                        {
                            e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(180, 210, 241)), new Rectangle(1, 1, (int)((panProgress.Width - 3) / PlayingSong.Duration * be.Position.TotalSeconds), 2));
                            e.Graphics.DrawLine(new Pen(Color.FromArgb(102, 148, 227)), new Point(1, 3), new Point((int)((panProgress.Width - 3) / PlayingSong.Duration * be.Position.TotalSeconds), 3));
                        }
                        catch { }
                    }
                }
            }
            catch { }
        }
        #endregion
        #region 各种BackgroundWorker事件
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            if (be.FileName != GetCachePath(PlayingSong))
            {
                string tpath = Helper.GetCachePath(Helper.CacheType.Thumbnail, PlayingSong.Album.Id + ".jpg");
                string lpath = Helper.GetCachePath(Helper.CacheType.Lyric, PlayingSong.Id + ".lrc");
                SongStreaming mdi = File.Exists(tpath) && ((PlayingSong.HasFullLyrics == File.Exists(lpath)) || (!PlayingSong.HasFullLyrics && File.Exists(lpath))) ? null : new SongStreaming(PlayingSong.Id);
                if (mdi != null) mdi.GetSongStreamingData();
                LoadPicture(PlayingSong, mdi);
                if (mdi == null)
                { if (PlayingSong.HasFullLyrics) e.Result = lpath; }
                else e.Result = mdi.DownloadLyrics();

                if (File.Exists(GetCachePath(PlayingSong) + ".cfg") || !File.Exists(GetCachePath(PlayingSong)))
                {
                    if (mdi == null)
                    {
                        mdi = new SongStreaming(PlayingSong.Id);
                        mdi.GetSongStreamingData();
                    }

                    mder.Url = mdi.SongUrl;
                    mder.FileName = GetCachePath(PlayingSong);
                    mder.Start();
                }
                else if (File.Exists(GetCachePath(PlayingSong)))
                {
                    mder.IsDownloadCompleted = true;
                    mder.DownloadedSize = 1; mder.FileLenght = 1;
                    ShowTextOnLyricShow(PlayingSong.ToString());
                }
                else
                {
                    e.Result = "return";
                    mder_ConnectionFailed(mder, null);
                }
            }
            else
            {
                this.Invoke(new Action(be.Play));
                RefreshInfos();
            }
        }

        private void mder_ConnectionFailed(object sender, EventArgs e)
        {
            if (closed) return;
            ConnectionFailed();
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Result != null && e.Result.ToString() == "return") return;
            if (e.Result != null && e.Result.ToString() != Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\GMusicBox\\temp.lrc")
            {
                Lyric l = new Lyric();
                l.GetLyric(e.Result.ToString(), System.Text.Encoding.UTF8);
                lyricShow1.SetLyric(l);
                ShowTextOnLyricShow(PlayingSong.ToString());
            }
            else lyricShow1.SetLyric(null);

            ShowPlaying();
            RefreshInfos();
        }

        private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                long max = StandardSetting.CacheMax * 1024 * 1024;

                List<FileInfo> files = new List<FileInfo>();
                files.AddRange((new DirectoryInfo(Helper.GetCachePath(Helper.CacheType.Music, ""))).GetFiles());

                for (int i = 0; i < files.Count; i++)
                {
                    for (int j = i + 1; j < files.Count; j++)
                    {
                        if (files[i].LastAccessTime > files[j].LastAccessTime)
                        {
                            FileInfo f = files[i];
                            files[i] = files[j];
                            files[j] = f;
                        }
                    }
                }

                while (GetSize(files.ToArray()) > max)
                {
                    files[0].Delete();
                    files.RemoveAt(0);
                }
            }
            catch { }
        }

        private long GetSize(FileInfo[] fi)
        {
            long size = 0;
            for (int i = 0; i < fi.Length; i++)
            {
                try
                {
                    size += fi[i].Length;
                }
                catch { }
            }
            return size;
        }
        #endregion
        #endregion
        #region 上方控制面板事件
        #region 上一首、播放、下一首
        private void btnNext_Click(object sender, EventArgs e)
        {
            if (playing[0] == -1 || playing[1] == -1) return;
            if (loopMode == 0)
            {
                int needplay = (int)(Microsoft.VisualBasic.VBMath.Rnd() * songs[playing[0]][playing[1]].Songs.Count);
                SetPlaying(needplay);
            }
            else
            {
                if (songs[playing[0]][playing[1]].Songs.Count == 0) return;
                else if (songs[playing[0]][playing[1]].Songs.Count == 1)
                {
                    be.Position = TimeSpan.FromSeconds(0);
                    be.Play();
                }
                else SetPlaying(playing[2] == songs[playing[0]][playing[1]].Songs.Count - 1 ? 0 : playing[2] + 1);
            }
        }

        private void btnPlayPause_Click(object sender, EventArgs e)
        {
            if (playing == null) return;
            if (be.PlayState == BassPlayState.Playing)
                be.Pause();
            else be.Play();
        }

        private void btnPrevious_Click(object sender, EventArgs e)
        {
            if (playing[0] == -1 || playing[1] == -1) return;
            if (loopMode == 0)
            {
                int needplay = (int)(Microsoft.VisualBasic.VBMath.Rnd() * songs[playing[0]][playing[1]].Songs.Count);
                SetPlaying(needplay);
            }
            else
            {
                if (songs[playing[0]][playing[1]].Songs.Count == 0) return;
                else if (songs[playing[0]][playing[1]].Songs.Count == 1)
                {
                    be.Position = TimeSpan.FromSeconds(0);
                    be.Play();
                }
                else SetPlaying(playing[2] == 0 ? songs[playing[0]][playing[1]].Songs.Count - 1 : playing[2] - 1);
            }
        }
        #endregion
        #region 音量区域
        private void btnMute_Click(object sender, EventArgs e)
        {
            //静音
            be.Mute = !be.Mute;
            RefreshMuteState();
        }

        private void tVolume_Scroll(object sender, EventArgs e)
        {
            if (tVolume.Tag == null || (tVolume.Tag != null && (double)tVolume.Tag != tVolume.Value))
            {
                tp.Show((int)(tVolume.Value * 100) == 0 ? "静音" : Math.Round(tVolume.Value * 100).ToString() + "%", tVolume, (int)(tVolume.Value * (tVolume.Width - 14) + 20), -2);
                tVolume.Tag = tVolume.Value;
                tVolume.Refresh();
            }
        }

        private void tVolume_ScrollEnd(object sender, EventArgs e)
        {
            tp.Hide(tVolume);
        }

        private void tVolume_ValueChanged(object sender, EventArgs e)
        {
            if (tVolume.AccessibleName != "")
            {
                tVolume.AccessibleName = "";
                return;
            }

            be.Volume = tVolume.Value;
            fm.tVolume.AccessibleName = " ";
            fm.tVolume.Value = tVolume.Value;
            RefreshMuteState();
        }
        #endregion
        #region 播放模式按钮
        private void btnaFor_Click(object sender, EventArgs e)
        {
            btnRandom.NormalImage = res.random_normal;
            btnforAll.NormalImage = res.forall_normal;
            btnaFor.NormalImage = res.afor_checked;
            loopMode = 2;
        }

        private void btnforAll_Click(object sender, EventArgs e)
        {
            btnRandom.NormalImage = res.random_normal;
            btnforAll.NormalImage = res.forall_checked;
            btnaFor.NormalImage = res.afor_normal;
            loopMode = 1;
        }

        private void btnRandom_Click(object sender, EventArgs e)
        {
            btnRandom.NormalImage = res.random_checked;
            btnforAll.NormalImage = res.forall_normal;
            btnaFor.NormalImage = res.afor_normal;
            loopMode = 0;
        }
        #endregion
        #region 其他事件
        private void panProgress_MouseDown(object sender, MouseEventArgs e)
        {
            //单击设置当前播放位置
            if (be.PlayState == BassPlayState.Playing && be.Handle != 0)
            {
                if (mder.FileLenght != 0 && mder.DownloadedSize != mder.FileLenght && (double)e.X / (panProgress.Width - 2) > (double)mder.DownloadedSize / mder.FileLenght) return;
                //if (be.Duration.TotalSeconds < PlayingSong.Duration)
                //    be.Load(wmp.URL);
                be.Position = TimeSpan.FromSeconds(PlayingSong.Duration / (panProgress.Width - 2) * e.X);
                panProgress.Invalidate();
            }
        }

        private void lnkMusicArtist_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            //搜索歌手
            txtSearch.Text = lnkMusicArtist.Text;
            txtSearch.ForeColor = Color.Black;
            btnSearch_Click(btnSearch, null);
        }

        private void btnEQ_Click(object sender, EventArgs e)
        {
            if (eqshw) feq.Close();
            else
            {
                feq.Show();
                feq.WindowState = FormWindowState.Normal;
                eqshw = true;
            }
        }
        #endregion
        #endregion
        #region 搜索相关
        private void btnSearch_Click(object sender, EventArgs e)
        {
            if (txtSearch.Text == "" || txtSearch.Text == "输入歌手、专辑、歌曲名称或歌词")
            {
                if (VTaskDialog.CanUseTankDialog())
                    VTaskDialog.ShowTaskDialog("请先输入搜索关键字再进行搜索。", "提示", "无法进行搜索", VTaskDialog.TaskDialogButton.OK, VTaskDialog.TaskDialogIcon.Warning);
                else MessageBox.Show("请先输入搜索关键字再进行搜索。", "无法进行搜索", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }

            frmSearch fs = new frmSearch(this, txtSearch.Text);
            fs.ShowDialog();
        }

        private void txtSearch_LostFocus(object sender, EventArgs e)
        {
            if (txtSearch.Text == "")
            {
                txtSearch.Text = "输入歌手、专辑、歌曲名称或歌词";
                txtSearch.ForeColor = Color.Silver;
            }
        }

        private void txtSearch_GotFocus(object sender, EventArgs e)
        {
            if (txtSearch.Text == "输入歌手、专辑、歌曲名称或歌词" && txtSearch.ForeColor == Color.Silver)
            {
                txtSearch.Text = "";
                txtSearch.ForeColor = Color.Black;
            }
        }

        private void txtSearch_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                btnSearch_Click(btnSearch, null);
            }
        }
        #endregion
        #region 列表事件
        private void lnkAddList_Click(object sender, EventArgs e)
        {
            ListViewItem lvi = new ListViewItem("新列表");
            lvi.Tag = new int[] { 0, songs[0].Count };
            lvwLists.Items.Add(lvi);
            songs[0].Add(new MusicList("", "新列表"));
            lvwLists.Items[lvwLists.Items.Count - 1].Selected = true;
            lvwLists.Items[lvwLists.Items.Count - 1].BeginEdit();
            if (!expLists.Expanded) expLists.Expanded = true;
        }

        private void lvwLists_AfterLabelEdit(object sender, LabelEditEventArgs e)
        {
            int list = lvwLists.Items[e.Item].Index;
            songs[0][list].Name = e.Label;
            SaveList(list);
            lvwLists.Items[e.Item].Selected = true;
        }

        private void ToggleList(object sender, EventArgs e)
        {
            ListView lv = ((ListView)sender);
            if (lv.SelectedItems.Count == 0) return;

            int[] listData = (int[])lv.SelectedItems[0].Tag;
            selected = listData;
            lblMusicCount.Text = "共 " + songs[listData[0]][listData[1]].Songs.Count.ToString() + " 首歌曲 ";
            lblListName.Text = songs[listData[0]][listData[1]].Name;

            if (selected[0] != 0 && lvwLists.SelectedItems.Count > 0) lvwLists.SelectedItems[0].Selected = false;
            if (selected[0] != 1 && lvwCharts.SelectedItems.Count > 0) lvwCharts.SelectedItems[0].Selected = false;
            if (selected[0] != 2 && lvwTopiclistings.SelectedItems.Count > 0) lvwTopiclistings.SelectedItems[0].Selected = false;

            lvwMusics.Items.Clear();
            foreach (Song item in songs[listData[0]][listData[1]].Songs)
                AddItemToMusic(item);

            chkSelectAll.Checked = false;
            ShowPlayingArrow(true);
            btnDelete.Enabled = lvwMusics.CheckedItems.Count > 0;
        }

        private void lvwMusics_DoubleClick(object sender, EventArgs e)
        {
            if (lvwMusics.SelectedItems.Count > 0)
            {
                int senderindex = lvwMusics.SelectedItems[0].Index;
                SetPlaying(selected[0], selected[1], senderindex);
            }
        }

        private void lvwMusics_ItemChecked(object sender, ItemCheckedEventArgs e)
        {
            btnAddTo.Enabled = lvwMusics.CheckedItems.Count > 0;
            if (selected[0] == 0) btnDelete.Enabled = lvwMusics.CheckedItems.Count > 0;
            else btnDelete.Enabled = false;
        }

        private void lvwMusics_MouseDown(object sender, MouseEventArgs e)
        {
            lvwMusicClick = e.X;
        }
        #endregion
        #region Expender事件
        private void expLists_ExpandedChanged(object sender, EventArgs e)
        {
            if (expLists.Expanded)
            {
                lvwTopiclistings.Visible = false;
                lvwLists.Visible = false;
                lvwCharts.Visible = false;

                if (StandardSetting.ExpanderAnimation)
                {
                    for (int i = 0; i < 221; i += 3)
                    {
                        if (expTopiclistingdir.Top < 266) expTopiclistingdir.Top += 4;
                        else expTopiclistingdir.Top = 266;

                        if (expChart.Top < 243) expChart.Top += 4;
                        else expChart.Top = 243;
                        panel9.Refresh();
                        System.Threading.Thread.Sleep(1);
                    }
                }
                else
                {
                    expTopiclistingdir.Top = 266;
                    expChart.Top = 243;
                }

                lvwLists.Visible = true;
                lvwTopiclistings.Visible = false;
                lvwCharts.Visible = false;
                expTopiclistingdir.Expanded = false;
                expChart.Expanded = false;
            }
        }

        private void expChart_ExpandedChanged(object sender, EventArgs e)
        {
            if (expChart.Expanded)
            {
                lvwTopiclistings.Visible = false;
                lvwLists.Visible = false;
                lvwCharts.Visible = false;

                if (StandardSetting.ExpanderAnimation)
                {
                    for (int i = 0; i < 221; i += 3)
                    {
                        if (expTopiclistingdir.Top < 266) expTopiclistingdir.Top += 4;
                        else expTopiclistingdir.Top = 266;

                        if (expChart.Top > 23) expChart.Top -= 4;
                        else expChart.Top = 23;

                        panel9.Refresh();
                        System.Threading.Thread.Sleep(1);
                    }
                }
                else
                {
                    expChart.Top = 23;
                    expTopiclistingdir.Top = 266;
                }

                expLists.Expanded = false;
                expTopiclistingdir.Expanded = false; expTopiclistingdir.Invalidate(); //expdret[2] = true;
                lvwLists.Visible = false;
                lvwTopiclistings.Visible = false;
                lvwCharts.Visible = true;
            }
        }

        private void expTopiclistingdir_ExpandedChanged(object sender, EventArgs e)
        {
            if (expTopiclistingdir.Expanded)
            {
                lvwTopiclistings.Visible = false;
                lvwLists.Visible = false;
                lvwCharts.Visible = false;

                if (StandardSetting.ExpanderAnimation)
                {
                    for (int i = 0; i < 221; i += 3)
                    {
                        if (expTopiclistingdir.Top > 46) expTopiclistingdir.Top -= 4;
                        else expTopiclistingdir.Top = 46;

                        if (expChart.Top > 23) expChart.Top -= 4;
                        else expChart.Top = 23;

                        panel9.Refresh();
                        System.Threading.Thread.Sleep(1);
                    }
                }
                else
                {
                    expTopiclistingdir.Top = 46;
                    expChart.Top = 23;
                }

                expChart.Expanded = false;
                expLists.Expanded = false;
                lvwTopiclistings.Visible = true;
                lvwLists.Visible = false;
                lvwCharts.Visible = false;
            }
        }
        #endregion
        #region 底部控制按钮事件
        private void chkSelectAll_CheckedChanged(object sender, EventArgs e)
        {
            for (int i = 0; i < lvwMusics.Items.Count; i++)
                lvwMusics.Items[i].Checked = chkSelectAll.Checked;
        }

        private void btnAddTo_Click(object sender, EventArgs e)
        {
            ContextMenu cms = new ContextMenu();
            for (int i = 0; i < lvwLists.Items.Count; i++)
            {
                MenuItem tsm = new MenuItem(lvwLists.Items[i].Text);
                tsm.Tag = lvwLists.Items[i];
                tsm.Click += new EventHandler(AddToListFromMenu);
                cms.MenuItems.Add(tsm);
            }
            cms.Show(btnAddTo, new Point(0, btnAddTo.Height));
        }

        private void AddToListFromMenu(object sender, EventArgs e)
        {
            ListViewItem lvi = (ListViewItem)((MenuItem)sender).Tag;
            List<Song> mbinfo = new List<Song>();
            int index = lvwLists.SelectedItems.Count > 0 ? lvwLists.SelectedItems[0].Index : 0;
            for (int i = 0; i < lvwMusics.CheckedItems.Count; i++)
                mbinfo.Add(songs[selected[0]][selected[1]][lvwMusics.CheckedItems[i].Index]);
            songs[0][lvi.Index].Songs.AddRange(mbinfo.ToArray());
            SaveList(lvi.Index);

            ShowMsg("列表内操作成功");
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            List<int> i = new List<int>();
            foreach (int item in lvwMusics.CheckedIndices)
                i.Add(item);
            DeleteMusic(i.ToArray());
            lvwMusics_ItemChecked(lvwMusics, null);
        }

        private void btnConfig_Click(object sender, EventArgs e)
        {
            frmConfig f = new frmConfig(this);
            if (sender is int) f.tabControl1.SelectedIndex = (int)sender;
            f.Show();
        }

        private void btnDownloader_Click(object sender, EventArgs e)
        {
            fder.Show();
            fder.WindowState = FormWindowState.Normal;
        }
        #endregion
        #region 时间事件
        private void timer1_Tick(object sender, EventArgs e)
        {
            label1.Text = double2Time(be.Position.TotalSeconds);
            if (label1.Text == "") label1.Text = "00:00";
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            panProgress.Invalidate();
            if (!be.IsTimerEnabled)
            {
                lyricShow1.CurrentProgress = be.Position.TotalSeconds;
                lyricShow1.RefreshDesktopLyric();
            }
        }

        private void timer3_Tick(object sender, EventArgs e)
        {
            if (StandardSetting.Subtitle)
            {
                string s1, s2;
                s1 = this.Text.Substring(1);
                s2 = this.Text.Substring(0, 1);
                this.Text = s1 + s2;
            }
            else
            {
                this.Text = PlayingSong.Name + " - 谷歌音乐盒 ";
                timer3.Enabled = false;
            }
        }

        private void be_Tick(object sender, EventArgs e)
        {
            try
            {
                if (lastDownload == 0 && lastplay == 0 && be.FileName != GetCachePath(PlayingSong) && mder.DownloadedSize / (double)mder.FileLenght >= 0.1 && mder.FileLenght != 0)
                {
                    be.Load(GetCachePath(PlayingSong), PlayingSong.ToString());
                    be.Play();
                    ShowTextOnLyricShow(PlayingSong.ToString());
                    ShowMsg("");
                    be.IsTimerEnabled = false;
                    lyricShow1.EnabledShowText = !PlayingSong.HasFullLyrics;
                }
                else if (mder.DownloadedSize / (double)mder.FileLenght <= 0.1)
                {
                    string info = PlayingSong.ToString() + "(" + Math.Round((double)mder.DownloadedSize / mder.FileLenght * 1000) + "%)";
                    ShowTextOnLyricShow(info);
                }
                else if (lastplay != 0 && lastDownload != 0 && be.Handle != 0)
                {
                    if ((mder.DownloadedSize - lastDownload) / (double)mder.FileLenght >= 0.1 || mder.IsDownloadCompleted)
                    {
                        be.Load(be.FileName, PlayingSong.ToString());
                        be.Play();
                        be.Position = TimeSpan.FromSeconds(lastplay);
                        be.IsTimerEnabled = false;

                        lastplay = 0; lastDownload = 0;
                    }
                }
                panProgress.Invalidate();
            }
            catch { }
        }

        private void timer5_Tick(object sender, EventArgs e)
        {
            panel3.Visible = false;
            timer5.Enabled = false;
        }
        #endregion
        #region 下载、歌词、彩铃
        private Song[] GetCurrentSelectedSonogs()
        {
            List<Song> ss = new List<Song>();

            for (int i = 0; i < lvwMusics.SelectedItems.Count; i++)
                ss.Add(songs[selected[0]][selected[1]][lvwMusics.SelectedItems[i].Index]);

            return ss.ToArray();
        }

        private void ViewLyrics(Song[] ss)
        {
            foreach (Song s in ss)
            {
                if (!s.HasFullLyrics) continue;

                SongStreaming stream = new SongStreaming(s.Id);
                stream.GetSongStreamingData();
                Lyric l = new Lyric();
                l.GetLyric(stream.DownloadLyrics(), Encoding.UTF8);
                frmLyrics fl = new frmLyrics(l);
                fl.Show();
            }
        }

        private void ViewRingtone(Song[] ss)
        {
            foreach (Song s in ss)
            {
                if (s.RingtoneUrl == null || s.RingtoneUrl.Trim() == "") continue;
                System.Diagnostics.Process.Start(s.RingtoneUrl);
            }
        }

        private void btnDownload_Click(object sender, EventArgs e)
        {
            if (PlayingSong != null)
                AddTask(new Song[] { PlayingSong });
        }

        private void mnuMusicDownload_Click(object sender, EventArgs e)
        {
            if (lvwMusics.SelectedItems.Count > 0)
                AddTask(GetCurrentSelectedSonogs());
        }

        private void btnLyrics_Click(object sender, EventArgs e)
        {
            if (PlayingSong != null)
                ViewLyrics(new Song[] { PlayingSong });
        }

        private void mnuMusicLyrics_Click(object sender, EventArgs e)
        {
            if (lvwMusics.SelectedItems.Count > 0)
                ViewLyrics(GetCurrentSelectedSonogs());
        }

        private void btnRing_Click(object sender, EventArgs e)
        {
            if (PlayingSong != null)
                ViewRingtone(new Song[] { PlayingSong });
        }

        private void mnuMusicRing_Click(object sender, EventArgs e)
        {
            if (lvwMusics.SelectedItems.Count > 0)
                ViewRingtone(GetCurrentSelectedSonogs());
        }
        #endregion
        #region 右键菜单事件
        #region 各种弹出时事件
        private void mnuDefaultSkin_Popup(object sender, EventArgs e)
        {
            for (int i = 0; i < 3; i++)
            {
                Color[] cs = lyricShow1.defaults[i];
                if (Helper.EqualsColor(LyricShowSetting.DTextColor, cs[0]))
                {
                    if (Helper.EqualsColor(LyricShowSetting.DTextColor1, cs[1]))
                    {
                        if (Helper.EqualsColor(LyricShowSetting.DHTextColor, cs[2]))
                        {
                            if (Helper.EqualsColor(LyricShowSetting.DHTextColor1, cs[3]))
                            {
                                mnuDefaultSkin.MenuItems[i].Checked = true;
                                continue;
                            }
                        }
                    }
                }
                mnuDefaultSkin.MenuItems[i].Checked = false;
            }
        }

        private void mnuNotify_Popup(object sender, EventArgs e)
        {
            if (hid || (mshw && mhid)) mnuMainVisible.Text = "显示主窗口(&V)";
            else mnuMainVisible.Text = "隐藏主窗口(&V)";
        }

        private void mnuList_Popup(object sender, EventArgs e)
        {
            mnuListDelete.Enabled = lvwLists.SelectedItems.Count > 0;
            mnuListRename.Enabled = lvwLists.SelectedItems.Count > 0;
            mnuMoveInList.Enabled = lvwLists.SelectedItems.Count > 0;
            if (lvwLists.SelectedItems.Count == 0) return;

            mnuLMoveDown.Enabled = true;
            mnuLMoveToEnd.Enabled = true;
            mnuLMoveToTop.Enabled = true;
            mnuLMoveUp.Enabled = true;

            for (int i = 0; i < lvwLists.SelectedItems.Count; i++)
                if (lvwLists.SelectedIndices[i] == 0)
                {
                    mnuLMoveUp.Enabled = false;
                    mnuLMoveToTop.Enabled = false;
                    break;
                }

            for (int i = 0; i < lvwLists.SelectedItems.Count; i++)
                if (lvwLists.SelectedIndices[i] == lvwLists.Items.Count - 1)
                {
                    mnuLMoveDown.Enabled = false;
                    mnuLMoveToEnd.Enabled = false;
                    break;
                }
        }

        private void mnuDLyricTransparent_Popup(object sender, EventArgs e)
        {
            for (int i = 0; i < mnuDLyricTransparent.MenuItems.Count; i++)
                mnuDLyricTransparent.MenuItems[i].Checked = (mnuDLyricTransparent.MenuItems[i].Text.Replace("&", "").Replace("%", "") == (LyricShowSetting.DOpacity * 100).ToString());
        }

        private void mnuMusic_Popup(object sender, EventArgs e)
        {
            mnuMusicAddTo.MenuItems.Clear();
            for (int i = 0; i < lvwLists.Items.Count; i++)
            {
                MenuItem tsm = new MenuItem(lvwLists.Items[i].Text);
                tsm.Tag = lvwLists.Items[i];
                tsm.Click += new EventHandler(AddSeledToListFromMenu);
                mnuMusicAddTo.MenuItems.Add(tsm);
            }
            if (lvwMusics.SelectedItems.Count == 1)
            {
                ListViewItem.ListViewSubItem ls = lvwMusics.SelectedItems[0].GetSubItemAt(lvwMusicClick, lvwMusics.SelectedItems[0].Position.Y);
                if (!(ls.Text.Length > 2 && ls.Text[2] == ':'))
                {
                    mnuSearchMusic.Visible = true;
                    mnuSearchMusic.Text = "搜索“" + ls.Text + "”(&S)...";
                    mnuSearchMusic.Tag = ls.Text;
                }
                else mnuSearchMusic.Visible = false;
            }
            else mnuSearchMusic.Visible = false;

            mnuMusicDelete.Visible = (selected[0] == 0);
            mnuSort.Visible = (selected[0] == 0);

            if (lvwMusics.SelectedItems.Count > 0)
            {
                if (songs[selected[0]][selected[1]][lvwMusics.SelectedItems[0].Index].CanBeDownloaded)
                    mnuMusicDownload.Visible = true;
                else mnuMusicDownload.Visible = false;
            }
        }

        private void AddSeledToListFromMenu(object sender, EventArgs e)
        {
            ListViewItem lvi = (ListViewItem)((MenuItem)sender).Tag;
            List<Song> mbinfo = new List<Song>();
            int index = lvwLists.SelectedItems.Count > 0 ? lvwLists.SelectedItems[0].Index : 0;
            for (int i = 0; i < lvwMusics.SelectedItems.Count; i++)
                mbinfo.Add(songs[selected[0]][selected[1]][lvwMusics.SelectedItems[i].Index]);

            songs[0][lvi.Index].Songs.AddRange(mbinfo.ToArray());
            SaveList(lvi.Index);
            ShowMsg("列表内操作成功");
        }

        private void mnuDesktopLyric_Popup(object sender, EventArgs e)
        {
            mnuKalaOK.Checked = LyricShowSetting.DKalaOK;
            if (lyricShow1.fdl.trans)
                mnuLockDesktopLyric.Text = "解锁桌面歌词(&L)";
            else mnuLockDesktopLyric.Text = "锁定桌面歌词(&L)";

            if (lyricShow1.hid)
                mnuShowOrHideDesktopLyric.Text = "显示桌面歌词(&S)";
            else mnuShowOrHideDesktopLyric.Text = "隐藏桌面歌词(&S)";
        }

        private void mnuVolumeControl_Popup(object sender, EventArgs e)
        {
            mnuVolumeAdd.Enabled = !(be.Volume == 1 || be.Mute);
            mnuVolumeDecrease.Enabled = !(be.Volume == 0 || be.Mute);
            mnuMute.Checked = be.Mute;
        }

        private void mnuPlayMode_Popup(object sender, EventArgs e)
        {
            for (int i = 0; i < 3; i++)
                mnuPlayMode.MenuItems[i].Checked = false;
            mnuPlayMode.MenuItems[loopMode].Checked = true;
        }
        #endregion
        #region 单击事件
        #region 列表相关
        private void mnuListInput_Click(object sender, EventArgs e)
        {
            if (lvwLists.SelectedItems.Count == 0) return;
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "列表文件(*.xml)|*.xml";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                MusicList ml = new MusicList();
                ml.Load(ofd.FileName);

                ListViewItem lvi = new ListViewItem(ml.Name);
                lvi.Tag = new int[] { 0, songs[0].Count };
                lvwLists.Items.Add(lvi);
                songs[0].Add(ml);
                SaveList(songs[0].Count - 1);
            }
            ofd.Dispose();
        }

        private void mnuListOutput_Click(object sender, EventArgs e)
        {
            if (lvwLists.SelectedItems.Count == 0) return;
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "列表文件(*.xml)|*.xml";
            sfd.FileName = lvwLists.SelectedItems[0].Text;
            if (sfd.ShowDialog() == DialogResult.OK)
                songs[0][lvwLists.SelectedItems[0].Index].Save(sfd.FileName);
            sfd.Dispose();
        }

        private void mnuListRename_Click(object sender, EventArgs e)
        {
            if (lvwLists.SelectedItems.Count > 0)
                lvwLists.SelectedItems[0].BeginEdit();
        }

        private void mnuListDelete_Click(object sender, EventArgs e)
        {
            if (lvwLists.SelectedItems.Count == 0) return;
            if (lvwLists.Items.Count <= 1) return;

            bool yes = false;
            if (VTaskDialog.CanUseTankDialog())
                yes = VTaskDialog.ShowTaskDialog("您确定要删除该列表吗？该操作将无法撤销。", "提示", "确认删除", VTaskDialog.TaskDialogButton.Yes | VTaskDialog.TaskDialogButton.No, VTaskDialog.TaskDialogIcon.Warning) == VTaskDialog.TaskDialogResult.Yes;
            else
                yes = MessageBox.Show("您确定要删除该列表吗？该操作将无法撤销。", "确认删除", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes;

            if (yes)
            {
                if (playing[0] == 0 && playing[1] == lvwLists.SelectedItems[0].Index)
                {
                    playing[1] = -1;
                    be.Stop();
                    EraserInfos();
                }
                if (playing[0] == 0 && playing[1] == 0 && songs[0][0].Songs.Count > playing[2]) playing[2] = 0;
                songs[0].RemoveAt(lvwLists.SelectedItems[0].Index);
                lvwLists.SelectedItems[0].Remove();
                lvwLists.Items[0].Selected = true;
                SaveAllLists();
            }
        }
        #endregion
        #region 托盘处菜单
        private void mnuFR5_Click(object sender, EventArgs e)
        {
            be.Position = TimeSpan.FromSeconds(be.Position.TotalSeconds - 5);
        }

        private void mnuFF5_Click(object sender, EventArgs e)
        {
            be.Position = TimeSpan.FromSeconds(be.Position.TotalSeconds + 5);
        }

        private void mnuVolumeAdd_Click(object sender, EventArgs e)
        {
            tVolume.Value += 0.05;
            RefreshMuteState();
        }

        private void munVolumeDecrease_Click(object sender, EventArgs e)
        {
            tVolume.Value -= 0.05;
            RefreshMuteState();
        }

        private void mnuExit_Click(object sender, EventArgs e)
        {
            closefmenu = true;
            this.Close();
        }

        private void mnuDefaultSkin1_Click(object sender, EventArgs e)
        {
            lyricShow1.SetDefault(0);
        }

        private void mnuDefaultSkin2_Click(object sender, EventArgs e)
        {
            lyricShow1.SetDefault(1);
        }

        private void mnuDefaultSkin3_Click(object sender, EventArgs e)
        {
            lyricShow1.SetDefault(2);
        }

        private void mnuDesktopLyricConfig_Click(object sender, EventArgs e)
        {
            btnConfig_Click(1, null);
        }

        private void mnuLockDesktopLyric_Click(object sender, EventArgs e)
        {
            if (lyricShow1.Penetrate())
                nfyMain.ShowBalloonTip(5000, "提示", "您可以右键单击托盘图标并在菜单中解锁桌面歌词。", ToolTipIcon.Info);
        }

        private void mnuShowOrHideDesktopLyric_Click(object sender, EventArgs e)
        {
            lyricShow1.OpenOrCloseDesktopLyric();
        }

        private void mnuHelp_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("http://music.google.org.cn/features.html");
        }

        private void mnuAbout_Click(object sender, EventArgs e)
        {
            frmAbout f = new frmAbout();
            f.Show();
        }

        private void mnuFeedback_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start("http://music.google.org.cn/feedback.html");
        }

        private void QuickSetDLTransparent(object sender, EventArgs e)
        {
            LyricShowSetting.DOpacity = double.Parse(((MenuItem)sender).Text.Replace("&", "").Replace("%", "")) / 100;
            lyricShow1.UpdateSkin();
            lyricShow1.fdl.ClearCache();
            lyricShow1.RefreshDesktopLyric();
        }

        private void mnuKalaOK_Click(object sender, EventArgs e)
        {
            LyricShowSetting.DKalaOK = !mnuKalaOK.Checked;
        }

        private void mnuConfig_Click(object sender, EventArgs e)
        {
            btnConfig_Click("center", e);
        }

        #endregion
        #region 音乐列表处右键菜单
        private void mnuSearchMusic_Click(object sender, EventArgs e)
        {
            txtSearch.Text = ((MenuItem)sender).Tag.ToString();
            btnSearch_Click(btnSearch, null);
        }

        private void mnuMusicDelete_Click(object sender, EventArgs e)
        {
            List<int> i = new List<int>();
            foreach (int item in lvwMusics.SelectedIndices)
                i.Add(item);
            DeleteMusic(i.ToArray());
            lvwMusics_ItemChecked(lvwMusics, null);
        }

        private void DeleteMusic(int[] indexes)
        {
            for (int i = 0; i < indexes.Length; i++)
            {
                int index = indexes[i] - i;
                if (playing[0] == 0 && playing[1] == selected[1])
                {
                    if (playing[2] > index) playing[2]--;
                    else if (playing[2] == index)
                    {
                        mder.Stop();
                        be.CloseFile();
                        EraserInfos();
                    }
                }

                songs[0][selected[1]].Songs.RemoveAt(index);
                lvwMusics.Items.RemoveAt(index);
            }
            SaveList(selected[1]);
            ShowPlayingArrow(true);
            ShowMsg("列表内操作成功");
        }
        #endregion
        #region 音乐移动
        private void mnuMoveToTop_Click(object sender, EventArgs e)
        {
            if (lvwMusics.SelectedItems.Count == 0) return;

            bool hasPlaying = false;
            int play = -1;
            if (playing[1] == selected[1])
            {
                for (int i = 0; i < lvwMusics.SelectedItems.Count; i++)
                {
                    if (lvwMusics.SelectedItems[i].Index >= playing[2]) hasPlaying = true;
                    if (lvwMusics.SelectedItems[i].Index == playing[2]) play = i;
                }
            }

            lvwMusics.BeginUpdate();
            int index = lvwMusics.SelectedItems[0].Index;
            if (hasPlaying) playing[2] += lvwMusics.SelectedItems.Count;
            if (play != -1) playing[2] = play;

            if (lvwMusics.SelectedItems[0].Index > 0)
            {
                for (int i = 0; i < lvwMusics.SelectedItems.Count; i++)
                {
                    ListViewItem lviSelectedItem = lvwMusics.SelectedItems[i];
                    int indexSelectedItem = lvwMusics.SelectedItems[i].Index;
                    lvwMusics.Items.RemoveAt(indexSelectedItem);
                    lvwMusics.Items.Insert(indexSelectedItem - index, lviSelectedItem);

                    Song t = songs[0][selected[1]][indexSelectedItem];
                    songs[0][selected[1]].Songs.RemoveAt(indexSelectedItem);
                    songs[0][selected[1]].Songs.Insert(indexSelectedItem - index, t);
                }
                SaveList(selected[1]);
            }
            lvwMusics.EndUpdate();
            if (lvwMusics.Items.Count > 0 && lvwMusics.SelectedItems.Count > 0)
            {
                lvwMusics.Focus();
                lvwMusics.SelectedItems[0].Focused = true;
                lvwMusics.SelectedItems[0].EnsureVisible();
            }
        }

        private void mnuMoveUp_Click(object sender, EventArgs e)
        {
            if (lvwMusics.SelectedItems.Count == 0) return;

            bool hasPlaying = false;
            int play = -1;
            if (playing[1] == selected[1])
            {
                for (int i = 0; i < lvwMusics.SelectedItems.Count; i++)
                {
                    if (lvwMusics.SelectedItems[i].Index - playing[2] <= 1 && lvwMusics.SelectedItems[i].Index - playing[2] >= 0) hasPlaying = true;
                    if (lvwMusics.SelectedItems[i].Index == playing[2]) play = lvwMusics.SelectedItems[i].Index;
                }
            }

            if (hasPlaying) playing[2]++;
            if (play != -1) playing[2] = play - 1;

            lvwMusics.BeginUpdate();
            if (lvwMusics.SelectedItems[0].Index > 0)
            {
                for (int i = 0; i < lvwMusics.SelectedItems.Count; i++)
                {
                    ListViewItem lviSelectedItem = lvwMusics.SelectedItems[i];
                    int indexSelectedItem = lvwMusics.SelectedItems[i].Index;
                    lvwMusics.Items.RemoveAt(indexSelectedItem);
                    lvwMusics.Items.Insert(indexSelectedItem - 1, lviSelectedItem);

                    Song t = songs[0][selected[1]].Songs[indexSelectedItem];
                    songs[0][selected[1]].Songs.RemoveAt(indexSelectedItem);
                    songs[0][selected[1]].Songs.Insert(indexSelectedItem - 1, t);
                    SaveList(selected[1]);
                }
            }
            lvwMusics.EndUpdate();
            if (lvwMusics.Items.Count > 0 && lvwMusics.SelectedItems.Count > 0)
            {
                lvwMusics.Focus();
                lvwMusics.SelectedItems[0].Focused = true;
                lvwMusics.SelectedItems[0].EnsureVisible();
            }
        }

        private void mnuMoveDown_Click(object sender, EventArgs e)
        {
            if (lvwMusics.SelectedItems.Count == 0) return;

            bool hasPlaying = false;
            int play = -1;

            if (playing[1] == selected[1])
            {
                for (int i = 0; i < lvwMusics.SelectedItems.Count; i++)
                {
                    if (lvwMusics.SelectedItems[i].Index - playing[2] >= -1 && lvwMusics.SelectedItems[i].Index - playing[2] <= 0) hasPlaying = true;
                    if (lvwMusics.SelectedItems[i].Index == playing[2]) play = lvwMusics.SelectedItems[i].Index;
                }
            }

            if (hasPlaying) playing[2]--;
            if (play != -1) playing[2] = play + 1;

            lvwMusics.BeginUpdate();
            int indexMaxSelectedItem = lvwMusics.SelectedItems[lvwMusics.SelectedItems.Count - 1].Index;
            if (indexMaxSelectedItem < lvwMusics.Items.Count - 1)
            {
                for (int i = lvwMusics.SelectedItems.Count - 1; i >= 0; i--)
                {
                    ListViewItem lviSelectedItem = lvwMusics.SelectedItems[i];
                    int indexSelectedItem = lvwMusics.SelectedItems[i].Index;
                    lvwMusics.Items.RemoveAt(indexSelectedItem);
                    lvwMusics.Items.Insert(indexSelectedItem + 1, lviSelectedItem);

                    Song t = songs[0][selected[1]].Songs[indexSelectedItem];
                    songs[0][selected[1]].Songs.RemoveAt(indexSelectedItem);
                    songs[0][selected[1]].Songs.Insert(indexSelectedItem + 1, t);
                    SaveList(selected[1]);
                }
            }
            lvwMusics.EndUpdate();
            if (lvwMusics.Items.Count > 0 && lvwMusics.SelectedItems.Count > 0)
            {
                lvwMusics.Focus();
                lvwMusics.SelectedItems[lvwMusics.SelectedItems.Count - 1].Focused = true;
                lvwMusics.SelectedItems[lvwMusics.SelectedItems.Count - 1].EnsureVisible();
            }
        }

        private void mnuMoveToEnd_Click(object sender, EventArgs e)
        {
            if (lvwMusics.SelectedItems.Count == 0) return;

            bool hasPlaying = false;
            int play = -1;
            if (playing[1] == selected[1])
            {
                for (int i = 0; i < lvwMusics.SelectedItems.Count; i++)
                {
                    if (lvwMusics.SelectedItems[i].Index <= playing[2]) hasPlaying = true;
                    if (lvwMusics.SelectedItems[i].Index == playing[2]) play = lvwMusics.Items.Count - 1 - i;
                }
            }

            lvwMusics.BeginUpdate();
            int index = lvwMusics.SelectedItems[lvwMusics.SelectedItems.Count - 1].Index;
            if (hasPlaying) playing[2] -= lvwMusics.SelectedItems.Count;
            if (play != -1) playing[2] = play;

            if (index < lvwMusics.Items.Count - 1)
            {
                for (int i = lvwMusics.SelectedItems.Count - 1; i >= 0; i--)
                {
                    ListViewItem lviSelectedItem = lvwMusics.SelectedItems[i];
                    int indexSelectedItem = lvwMusics.SelectedItems[i].Index;
                    lvwMusics.Items.RemoveAt(indexSelectedItem);
                    lvwMusics.Items.Insert(indexSelectedItem + lvwMusics.Items.Count - index, lviSelectedItem);

                    Song t = songs[0][selected[1]].Songs[indexSelectedItem];
                    songs[0][selected[1]].Songs.RemoveAt(indexSelectedItem);
                    songs[0][selected[1]].Songs.Insert(indexSelectedItem + lvwMusics.Items.Count - index - 1, t);
                    SaveList(selected[1]);
                }
            }
            lvwMusics.EndUpdate();
            if (lvwMusics.Items.Count > 0 && lvwMusics.SelectedItems.Count > 0)
            {
                lvwMusics.Focus();
                lvwMusics.SelectedItems[lvwMusics.SelectedItems.Count - 1].Focused = true;
                lvwMusics.SelectedItems[lvwMusics.SelectedItems.Count - 1].EnsureVisible();
            }
        }
        #endregion
        #region 列表移动
        private void mnuLMoveToTop_Click(object sender, EventArgs e)
        {
            if (lvwLists.SelectedItems.Count == 0) return;
            for (int i = 0; i < lvwLists.SelectedItems.Count; i++)
                if (lvwLists.SelectedIndices[i] == 0) return;

            lvwLists.BeginUpdate();
            int index = lvwLists.SelectedItems[0].Index;
            if (lvwLists.SelectedItems[0].Index > 0)
            {
                for (int i = 0; i < lvwLists.SelectedItems.Count; i++)
                {
                    ListViewItem lviSelectedItem = lvwLists.SelectedItems[i];
                    int indexSelectedItem = lvwLists.SelectedItems[i].Index;
                    if (playing[0] == 0)
                        if (indexSelectedItem == playing[1]) playing[1] = indexSelectedItem - index;
                        else if (indexSelectedItem > playing[1]) playing[1]++;
                        else if (indexSelectedItem < playing[1]) playing[1]--;
                    lvwLists.Items.RemoveAt(indexSelectedItem);
                    lvwLists.Items.Insert(indexSelectedItem - index, lviSelectedItem);
                    lvwLists.Items[indexSelectedItem].Tag = new int[] { 0, indexSelectedItem };
                    lvwLists.Items[indexSelectedItem - index].Tag = new int[] { 0, indexSelectedItem - index };

                    MusicList t = songs[0][indexSelectedItem];
                    songs[0].RemoveAt(indexSelectedItem);
                    songs[0].Insert(indexSelectedItem - index, t);
                }
            }
            lvwLists.EndUpdate();
            if (lvwLists.Items.Count > 0 && lvwLists.SelectedItems.Count > 0)
            {
                lvwLists.Focus();
                lvwLists.SelectedItems[0].Focused = true;
                lvwLists.SelectedItems[0].EnsureVisible();
            }
            SaveAllLists();
            ToggleList(lvwLists, null);
        }

        private void mnuLMoveUp_Click(object sender, EventArgs e)
        {
            if (lvwLists.SelectedItems.Count == 0) return;
            for (int i = 0; i < lvwLists.SelectedItems.Count; i++)
                if (lvwLists.SelectedIndices[i] == 0) return;

            lvwLists.BeginUpdate();
            if (lvwLists.SelectedItems[0].Index > 0)
            {
                for (int i = 0; i < lvwLists.SelectedItems.Count; i++)
                {
                    ListViewItem lviSelectedItem = lvwLists.SelectedItems[i];
                    int indexSelectedItem = lvwLists.SelectedItems[i].Index;
                    if (playing[0] == 0)
                        if (indexSelectedItem == playing[1]) playing[1] = indexSelectedItem - 1;
                        else if (indexSelectedItem > playing[1]) playing[1]++;
                        else if (indexSelectedItem < playing[1]) playing[1]--;
                    lvwLists.Items.RemoveAt(indexSelectedItem);
                    lvwLists.Items.Insert(indexSelectedItem - 1, lviSelectedItem);
                    lvwLists.Items[indexSelectedItem].Tag = new int[] { 0, indexSelectedItem };
                    lvwLists.Items[indexSelectedItem - 1].Tag = new int[] { 0, indexSelectedItem - 1 };

                    MusicList t = songs[0][indexSelectedItem];
                    songs[0].RemoveAt(indexSelectedItem);
                    songs[0].Insert(indexSelectedItem - 1, t);
                }
            }
            lvwLists.EndUpdate();
            if (lvwLists.Items.Count > 0 && lvwLists.SelectedItems.Count > 0)
            {
                lvwLists.Focus();
                lvwLists.SelectedItems[0].Focused = true;
                lvwLists.SelectedItems[0].EnsureVisible();
            }
            SaveAllLists();
            ToggleList(lvwLists, null);
        }

        private void mnuLMoveDown_Click(object sender, EventArgs e)
        {
            if (lvwLists.SelectedItems.Count == 0) return;
            for (int i = 0; i < lvwLists.SelectedItems.Count; i++)
                if (lvwLists.SelectedIndices[i] == lvwLists.Items.Count - 1) return;

            lvwLists.BeginUpdate();
            int indexMaxSelectedItem = lvwLists.SelectedItems[lvwLists.SelectedItems.Count - 1].Index;
            if (indexMaxSelectedItem < lvwLists.Items.Count - 1)
            {
                for (int i = lvwLists.SelectedItems.Count - 1; i >= 0; i--)
                {
                    ListViewItem lviSelectedItem = lvwLists.SelectedItems[i];
                    int indexSelectedItem = lvwLists.SelectedItems[i].Index;
                    if (playing[0] == 0)
                        if (indexSelectedItem == playing[1]) playing[1] = indexSelectedItem + 1;
                        else if (indexSelectedItem > playing[1]) playing[1]++;
                        else if (indexSelectedItem < playing[1]) playing[1]--;
                    lvwLists.Items.RemoveAt(indexSelectedItem);
                    lvwLists.Items.Insert(indexSelectedItem + 1, lviSelectedItem);
                    lvwLists.Items[indexSelectedItem].Tag = new int[] { 0, indexSelectedItem };
                    lvwLists.Items[indexSelectedItem + 1].Tag = new int[] { 0, indexSelectedItem + 1 };

                    MusicList t = songs[0][indexSelectedItem];
                    songs[0].RemoveAt(indexSelectedItem);
                    songs[0].Insert(indexSelectedItem + 1, t);
                }
            }
            lvwLists.EndUpdate();
            if (lvwLists.Items.Count > 0 && lvwLists.SelectedItems.Count > 0)
            {
                lvwLists.Focus();
                lvwLists.SelectedItems[lvwLists.SelectedItems.Count - 1].Focused = true;
                lvwLists.SelectedItems[lvwLists.SelectedItems.Count - 1].EnsureVisible();
            }
            SaveAllLists();
            ToggleList(lvwLists, null);
        }

        private void mnuLMoveToEnd_Click(object sender, EventArgs e)
        {
            if (lvwLists.SelectedItems.Count == 0) return;
            for (int i = 0; i < lvwLists.SelectedItems.Count; i++)
                if (lvwLists.SelectedIndices[i] == lvwLists.Items.Count - 1) return;

            lvwLists.BeginUpdate();
            int index = lvwLists.SelectedItems[lvwLists.SelectedItems.Count - 1].Index;

            if (index < lvwLists.Items.Count - 1)
            {
                for (int i = lvwLists.SelectedItems.Count - 1; i >= 0; i--)
                {
                    ListViewItem lviSelectedItem = lvwLists.SelectedItems[i];
                    int indexSelectedItem = lvwLists.SelectedItems[i].Index;
                    int dst = indexSelectedItem + lvwLists.Items.Count - index - 1;

                    if (playing[0] == 0)
                        if (indexSelectedItem == playing[1]) playing[1] = dst;
                        else if (indexSelectedItem > playing[1]) playing[1]++;
                        else if (indexSelectedItem < playing[1]) playing[1]--;
                    lvwLists.Items.RemoveAt(indexSelectedItem);
                    lvwLists.Items.Insert(indexSelectedItem + lvwLists.Items.Count - index, lviSelectedItem);
                    lvwLists.Items[indexSelectedItem].Tag = new int[] { 0, indexSelectedItem };
                    lvwLists.Items[dst].Tag = new int[] { 0, dst };

                    MusicList t = songs[0][indexSelectedItem];
                    songs[0].RemoveAt(indexSelectedItem);
                    songs[0].Insert(dst, t);
                }
            }
            lvwLists.EndUpdate();
            if (lvwLists.Items.Count > 0 && lvwLists.SelectedItems.Count > 0)
            {
                lvwLists.Focus();
                lvwLists.SelectedItems[lvwLists.SelectedItems.Count - 1].Focused = true;
                lvwLists.SelectedItems[lvwLists.SelectedItems.Count - 1].EnsureVisible();
            }
            SaveAllLists();
            ToggleList(lvwLists, null);
        }
        #endregion
        #endregion
        #endregion
        #region 歌词拖动
        private void lyricShow1_ProcessChangedFromDrag(object sender, EventArgs e)
        {
            //if (wmp.currentMedia != null && be.Duration.TotalSeconds < lyricShow1.CurrentProgress)
            //    be.Load(wmp.URL;
            be.Position = TimeSpan.FromSeconds(lyricShow1.CurrentProgress);
        }

        private void lyricShow1_MouseMove(object sender, MouseEventArgs e)
        {
            if (lyricShow1.dragging && e.Button == MouseButtons.Left)
                be.Pause();
        }

        private void lyricShow1_MouseUp(object sender, MouseEventArgs e)
        {
            if (lyricShow1.dragging && e.Button == MouseButtons.Left)
                be.Play();
        }

        private void lyricShow1_PreLyricDrag(object sender, CancelEventArgs e)
        {
            if (((double)mder.DownloadedSize / mder.FileLenght <= 0.1) ||
                (be.PlayState != BassPlayState.Playing && 
                 be.PlayState != BassPlayState.Paused)) e.Cancel = true;
        }

        private void lyricShow1_PreDraggingLyric(object sender, CancelEventArgs e)
        {
            if (be.Handle != 0 && be.Position.TotalSeconds / be.Duration.TotalSeconds > (double)mder.DownloadedSize / mder.FileLenght - 0.05 && !mder.IsDownloadCompleted)
                e.Cancel = true;
        }
        #endregion
        #region 其他事件
        private void mder_DownloadComplete(object sender, EventArgs e)
        {
            ShowMsg("歌曲加载完成");
            //if (be.PlayState == BassPlayState.Playing) be.IsTimerEnabled = false;
        }

        private void mder_Connected(object sender, EventArgs e)
        {
            ShowMsg("");
        }

        public void nfyMain_DoubleClick(object sender, EventArgs e)
        {
            if (mshw)
            {
                if (mhid) { fm.Show(); fm.Activate(); fm.WindowState = FormWindowState.Normal; mhid = false; }
                else { fm.Hide(); mhid = true; }
            }
            else
            {
                if (hid) { this.Show(); this.Activate(); this.WindowState = FormWindowState.Normal; hid = false; }
                else { this.Hide(); hid = true; }
            }
        }

        private void hotkey_OnHotKey(int HotKeyID)
        {
            for (int i = 0; i < hotkeys.Length; i++)
            {
                if (hotkeys[i] == -1) continue;
                if (hotkeys[i] == HotKeyID)
                {
                    if (i == 0) nfyMain_DoubleClick(nfyMain, new EventArgs());
                    else if (i == 1 || i == 7) btnPlayPause_Click(btnPlayPause, new EventArgs());
                    else if (i == 2 || i == 8) btnPrevious_Click(btnPrevious, new EventArgs());
                    else if (i == 3 || i == 9) btnNext_Click(btnNext, new EventArgs());
                    else if (i == 4) btnMute_Click(btnMute, new EventArgs());
                    else if (i == 5 || i == 6)
                    {
                        if (i == 5)
                        {
                            if (be.Volume + 0.05 > 1) be.Volume = 1;
                            else be.Volume += 0.05;
                        }
                        if (i == 6)
                        {
                            if (be.Volume - 0.05 < 0) be.Volume = 0;
                            else be.Volume -= 0.05;
                        }

                        RefreshMuteState();
                    }
                }
            }
        }

        private void pictureBox4_LoadCompleted(object sender, AsyncCompletedEventArgs e)
        {
            try
            {
                string path = pictureBox4.Tag.ToString();
                Helper.CreateDirectory(Path.GetDirectoryName(path));
                pictureBox4.Image.Save(path, System.Drawing.Imaging.ImageFormat.Jpeg);
                fpt.ImageOK();
            }
            catch { }
        }

        private void mnuMusicPlay_Click(object sender, EventArgs e)
        {
            if (lvwMusics.SelectedIndices.Count == 0) return;
            playing[0] = selected[0];
            SetPlaying(selected[1], lvwMusics.SelectedIndices[0]);
        }

        private void btnGotoMiniMode_Click(object sender, EventArgs e)
        {
            this.Hide();
            fm.Show();
            mhid = false;
            mshw = true;
        }
        #endregion
    }
}
